/*
******************************************************************************************************* 
**  Copyright (C) 2019, 苏州检易生物科技有限公司 
**  All rights reserved. 
** 
**  FileName:       	uart.c
**  Description:	
**  Author:        	 
**  Version				v0.1
**  Date:           	2019-05-22
**	Function List： 
**  History:         
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                              	调试开关
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                             INCLUDE FILES
*********************************************************************************************************
*/
#include "BspUART.h"


/*
*********************************************************************************************************
*                                              	宏定义
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                              	结构体定义
*********************************************************************************************************
*/



 
/*
*********************************************************************************************************
*                                              	函数原型声明
*********************************************************************************************************
*/
static void bsp_uart_irq_handler(bsp_uart_t * p_uart);

/*
*********************************************************************************************************
*                                              	全局变量定义
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*                                              	模块静态变量定义
*********************************************************************************************************
*/
static bsp_uart_t m_bsp_uart;
/*
*********************************************************************************************************
*                                              	函数定义
*********************************************************************************************************
*/

bsp_uart_t* bsp_uart_init(USART_TypeDef* uart,uint32_t baudrate,
	uart_callback pfn_tx_cb,uart_callback pfn_rx_cb)
{
	m_bsp_uart.baudrate = baudrate;
	m_bsp_uart.uart_idle_callback = pfn_rx_cb;
	m_bsp_uart.uart_tc_callback = pfn_tx_cb;
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟
 
	//串口1对应引脚复用映射
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9复用为USART1
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10复用为USART1
	
	//USART1端口配置
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10 ; //GPIOA9与GPIOA10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//速度50MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
	GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9，PA10
	

   //USART1 初始化设置
	USART_InitStructure.USART_BaudRate = baudrate;//波特率设置
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
	USART_Init(USART1, &USART_InitStructure); //初始化串口1
	
	USART_Cmd(USART1, ENABLE);  //使能串口1 
	
	USART_ClearFlag(USART1, USART_FLAG_TC);
		
	USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启相关中断

	//Usart1 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);
	DMA_InitTypeDef DMA_InitStructure;
	DMA_DeInit(DMA2_Stream2); 

	DMA_InitStructure.DMA_Channel             = DMA_Channel_4;               /* 配置DMA通道 */
	DMA_InitStructure.DMA_PeripheralBaseAddr  = (uint32_t)(&(USART1->DR));   /* 源 */
	DMA_InitStructure.DMA_Memory0BaseAddr     = (uint32_t)(m_bsp_uart.rxbuff);             /* 目的 */
	DMA_InitStructure.DMA_DIR                 = DMA_DIR_PeripheralToMemory;    /* 方向 */
	DMA_InitStructure.DMA_BufferSize          = UART_RX_BUFF_SIZE;                    /* 长度 */                  
	DMA_InitStructure.DMA_PeripheralInc       = DMA_PeripheralInc_Disable;    /* 外设地址是否自增 */
	DMA_InitStructure.DMA_MemoryInc           = DMA_MemoryInc_Enable;         /* 内存地址是否自增 */
	DMA_InitStructure.DMA_PeripheralDataSize  = DMA_MemoryDataSize_Byte;      /* 目的数据带宽 */
	DMA_InitStructure.DMA_MemoryDataSize      = DMA_MemoryDataSize_Byte;      /* 源数据宽度 */
	DMA_InitStructure.DMA_Mode                = DMA_Mode_Normal;              /* 单次传输模式/循环传输模式 */
	DMA_InitStructure.DMA_Priority            = DMA_Priority_VeryHigh;        /* DMA优先级 */
	DMA_InitStructure.DMA_FIFOMode            = DMA_FIFOMode_Disable;          /* FIFO模式/直接模式 */
	DMA_InitStructure.DMA_FIFOThreshold       = DMA_FIFOThreshold_HalfFull; /* FIFO大小 */
	DMA_InitStructure.DMA_MemoryBurst         = DMA_MemoryBurst_Single;       /* 单次传输 */
	DMA_InitStructure.DMA_PeripheralBurst     = DMA_PeripheralBurst_Single;
	DMA_Init(DMA2_Stream2, &DMA_InitStructure);
	USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);
	DMA_Cmd(DMA2_Stream2,ENABLE);
	return &m_bsp_uart;
}
void USART1_IRQHandler(void)                	//串口1中断服务程序
{
	uint16_t rx_cnt;
	if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)  //接收中断
	{
		USART1->SR;  
		USART1->DR; 
		DMA_Cmd(DMA2_Stream2,DISABLE);  
		DMA_ClearFlag(DMA2_Stream2,DMA_FLAG_TCIF2);  
		rx_cnt = UART_RX_BUFF_SIZE - DMA_GetCurrDataCounter(DMA2_Stream2);
		if(m_bsp_uart.uart_idle_callback)
			m_bsp_uart.uart_idle_callback(&m_bsp_uart,m_bsp_uart.rxbuff,rx_cnt);
		DMA_SetCurrDataCounter(DMA2_Stream2,UART_RX_BUFF_SIZE);  
		DMA_Cmd(DMA2_Stream2,ENABLE);	
		USART_ClearFlag(USART1,USART_FLAG_IDLE);
	} 
//	if(USART_GetITStatus(USART1, USART_IT_TC) != RESET)  //422 EN 管脚需要在TC中断中切到发送状态
//	{
//		USART_ClearFlag(USART1,USART_FLAG_TC);
//		uart_rx_en(uart422_handle);
//		if(uart422_handle->pfn_write_callback)
//			uart422_handle->pfn_write_callback(uart422_handle,uart422_handle->tx_buf,uart422_handle->tx_cnt);
//	}
} 
void	uart_write(bsp_uart_t handle, uint8_t* buf, uint16_t size)
{
	for(uint16_t i=0;i<size;i++)
	{
		USART_SendData(USART1,buf[i]);	
		while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
	}
//	USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
//	USART_ITConfig(USART1, USART_IT_TC, ENABLE);
	return;
}
void bsp_uart_send_byte(bsp_uart_t* handle,uint8_t byte)
{
	USART_SendData(USART1,byte);	
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}
//uart_err_t	uart_asyn_write(uart_handle_t handle, uint8_t* buf, uint16_t size)
//{
//	DMA_Cmd(handle->p_tx_dma, DISABLE);                      //关闭DMA传输 
//	while (DMA_GetCmdStatus(handle->p_tx_dma) != DISABLE);	//确保DMA可以被设置  
//	if(buf!=NULL)
//	{
//		handle->p_tx_dma->M0AR = (uint32_t)buf;
//	}
//	DMA_SetCurrDataCounter(handle->p_tx_dma,size);          //数据传输量  
//	uart_tx_en(handle);
//	DMA_Cmd(handle->p_tx_dma, ENABLE);                      //开启DMA传输 
//	return UART_ERR_NONE;
//}